---
jupytext:
  encoding: '# -*- coding: utf-8 -*-'
  formats: md:myst,ipynb
  text_representation:
    extension: .md
    format_name: myst
    format_version: 0.13
    jupytext_version: 1.16.4
kernelspec:
  display_name: Python 3 (ipykernel)
  language: python
  name: python3
---

```{code-cell}
import mmf_setup;mmf_setup.nbinit()
```

# Dark-Bright Soliton Trains

+++

This notebook is to replicated some of the work done in the paper "Generation of Dark-Bright Soliton Trains in Superfluid-Superfluid Counterflow" [PhysRev 106 065302](https://journals.aps.org/prl/abstract/10.1103/PhysRevLett.106.065302)

The simulations some in the paper are 3D, here will use a 1D aproximation that asumes the radia directions have a guassian profile (called tube/tube2)

+++

## Experimental setup

+++

* $N_{tot} \approx 450000$

* States: $\left|1,1 \right>$ and $\left|2,2\right>$ with scatterling Lenghts $a_{11} = 100.40 \text{ a.u.}$,  $a_{22} \approx a_{12} = 98.98 \text{ a.u.}$

* initial state 70% $\left|1,1 \right>$ and 30% $\left|2,2\right>$

* Initial states look to be around 600 microns long, $R_{TF} = 300$

* Counterflow is ramped on linearly for 1 sec (1000ms) and held constant

* Trap frequencies: $2π·1.2$ Hz axially, $2π·174$ Hz radially in the horizontal plane, and $2π · 120 Hz$ radially in the vertical direction. $w_s = 2\pi(1.2,174,120)$

* $7 ms$ of free expansion before imaging

```{code-cell}
from gpe.soc_soliton import Experiment, u
from gpe import utils

class ExperimentST(Experiment):
    states = ((1, -1), (2, -2))
    Rx_TF = 600.0*u.micron
    t_unit = u.ms
    detuning_kHz = None
    detuning_E_R = 0.

    B_gradient_mG_cm = 7           # Magnetic field gradients are on the order of 5-10 mG/cm
    recoil_frequency_Hz = 1843.0
    #recoil_frequency_Hz = 1.
    rabi_frequency_E_R = 0.
    trapping_frequencies_Hz = (1.2, 174, 120)

    initial_imbalance = 0.7        # Nothing RF transfered, all in state[...][0]

    t__expand = 9000.              # Time for expansion
    t__counterflow_ramp = 1000.


    @property
    def t__expansion(self):
        return (self.t__counterflow_ramp
                + self.t__expand)


    def init(self):
        Experiment.init(self)

        self._B_gradient = utils.get_smooth_transition(
                [0.0, self.B_gradient],
                durations=[0.0],
                transitions=[self.t__counterflow_ramp]
            )

    def B_gradient_t_(self, t_):
        return self._B_gradient(t_)
```

## Initial state

```{code-cell}
%pylab inline --no-import-all
from gpe import utils, bec2, tube2, minimize, soc_soliton
from gpe.soc_soliton import u

reload(bec2)
reload(tube2)
reload(soc_soliton)

experiment = ExperimentST(
    State=soc_soliton.State2tube,
    Lxyz=(1000*u.micron,),
    Nxyz=(2**7,),
    N=4.5e5)

s0 = experiment.get_initial_state(cool_dt_t_scale=0.00114)
#s0.constraint = 'Nab'

#s0.plot()
# Don't fix N... this should respect mu and Rx_TF
m = minimize.MinimizeState(s0, fix_N=True)
s = m.minimize()
s.plot()
```

$$

$$

```{code-cell}
def get_n(mus, gs):
    mua, mub = mus
    ga, gb, gab = gs
    G = np.array([[ga,gab],
                  [gab,gb]])
    print(np.linalg.inv(G))
    na, nb = ns = np.asarray(np.linalg.solve(G,mus))
    ia = np.where(na < 0.)
    na[ia] = 0.0
    nb[ia] = (np.maximum(mub, 0)/gb)[ia]
    ib = np.where(nb < 0.)
    nb[ib] = 0
    na[ib] = (np.maximum(mua, 0)/gb)[ib]
    return na, nb

#mus = np.asarray([-.1+s.mu,s.mu]).reshape(s[...].shape)
#mus = s.mu
na, nb = get_n(s.mu-s.get_VHO(), s.gs)

na.shape,nb.shape
plt.plot(s.xyz[0],na)
plt.plot(s.xyz[0],nb)
 
#plt.semilogy(s.xyz[0],na)
#plt.semilogy(s.xyz[0],nb)
 
```

```{code-cell}

```

```{code-cell}

```

```{code-cell}
s1 = s.copy()

new_state = np.ones(s1[...].shape)
s1[...] = np.asarray([np.sqrt(0.5017)*new_state[0],
                      np.sqrt(0.4981)*new_state[1]])


Hy = s1.get_Hy(subtract_mu=True)[...]
na, nb = (Hy.conj()*Hy).real
plt.semilogy(s.xyz[0],na)
plt.semilogy(s.xyz[0],nb)
```

```{code-cell}

```

```{code-cell}

```

```{code-cell}

```

```{code-cell}

```

```{code-cell}
va,vb,vab = s.get_V()
vea,veb,veab = s.get_Vext()

na,nb = s.get_density()



plt.figure(figsize=(20,10))
plt.subplot(311)
plt.plot(s.xyz[0], va)
plt.plot(s.xyz[0], vb)
plt.subplot(312)
plt.plot(s.xyz[0], vea)
plt.plot(s.xyz[0], veb)
plt.subplot(313)
plt.plot(s.xyz[0], (va-vea))
plt.plot(s.xyz[0], s.gs[1]*nb)

#print((va-vea),(vb-veb))
```

```{code-cell}
na,nb = s0.get_density()
x = s0.xyz[0]

plt.plot(x,na)
#plt.plot(x,nb)
```

```{code-cell}
%pylab inline --no-import-all
from gpe import utils, bec2, tube2, minimize, soc_soliton
from gpe.soc_soliton import u

reload(bec2)
reload(tube2)
reload(soc_soliton)

experiment = ExperimentST(
    State=soc_soliton.State2tube,
    Lxyz=(1000*u.micron,),
    Nxyz=(2**7,),
    N=4.5e5)
s0 = experiment.get_initial_state(cool_dt_t_scale=0.00114)
s0.constraint = 'Nab'
s0.plot()
# Don't fix N... this should respect mu and Rx_TF
m = minimize.MinimizeState(s0, fix_N=True)
s = m.minimize()
s.plot()
```

## Evolve

```{code-cell}
from IPython.display import clear_output, display
from pytimeode.evolvers import EvolverABM
from mmfutils.contexts import NoInterrupt

#s1 = s.copy()
s1.cooling_phase = 1+0.000001j
#s1.ws[0] = 0.
#s1[...][1] = 0.

e = EvolverABM(s1, dt=.0005*s.t_scale)
fig = None
with NoInterrupt() as interrupted:
    while not interrupted:
        e.evolve(200)
        plt.clf()
        fig = e.y.plot(fig)
        display(fig)
        clear_output(wait=True)
```

```{code-cell}

```

```{code-cell}

```

```{code-cell}

```

```{code-cell}

```

```{code-cell}

```

```{code-cell}

```

```{code-cell}

```

```{code-cell}

```

## Magnetic Gradient Linear Ramp


Currently get_smooth_transitions() is used to ramp on/off different parameters. This function is not the same as the linear ramp used in the experiments so this is an attempt to find a better linear ramp.

+++

Slope in middle is:

$$
  \left(\frac{\alpha\pi}{2}\right)^{1/(2p+1)}
$$

```{code-cell}
%pylab inline 
from gpe.utils import step

x = np.linspace(0, 1, 10000)
#plt.plot(x, np.vectorize(step)(x, 1, alpha=0.4))
alpha = 1.0
def rt(p, x):
    return np.sign(x)*abs(x)**(1./(2*p+1))

p = 1
alpha = 1.0
y = (1 + rt(p, np.tanh(alpha*np.tan(np.pi*(2*x-1)**(2*p+1)/2))))/2
plt.plot(x, y)
plt.plot(x, x)
```

```{code-cell}
%pylab inline 
from gpe.utils import step

x = np.linspace(0, 1, 10000)
#plt.plot(x, np.vectorize(step)(x, 1, alpha=0.4))
alpha = 1.0
def rt(p, x):
    return np.sign(x)*abs(x)**(1./(2*p+1))

alpha = 2./np.pi
y = (1 + np.tanh(alpha*np.tan(np.pi*(2*x-1)/2)))/2
plt.plot(x, y)
plt.plot(x, x)
```

```{code-cell}
np.
```

```{code-cell}

```
